# Copyright (c) 2021-2023 Alibaba Cloud Computing Ltd.
# SPDX-License-Identifier: MulanPSL-2.0

import json
import logging

from tornado.web import RequestHandler
from collections import defaultdict

from agent.controller import get_feature_handler, get_domain_handler

logger = logging.getLogger('common')


class ConfigureHandler(RequestHandler):
    def post(self):
        request_data = json.loads(self.request.body)
        logger.debug("configure requests: {}".format(request_data))
        
        configure_result = defaultdict(dict)
        for domain_name, param_list in request_data['data'].items():
            handled_feature = []
            configure_result[domain_name]['param_result'] = {}
            
            for param_name, param_info in param_list.items():
                try:
                    feature_handler = get_feature_handler(domain_name, param_name)
                    try:
                        handled_feature.append(param_name)
                        if request_data["readonly"]:
                            value = feature_handler.get_value()
                            configure_result[domain_name]['param_result'][param_name] = {"suc": True, "value": value, "msg": ""}
                            
                        else:
                            feature_handler.set_value(param_info['value'])
                            configure_result[domain_name]['param_result'][param_name] = {"suc": True, "value": "", "msg": ""}
                            
                    except Exception as e:
                        logger.error("configure '{}:{}' failed: {}".format(domain_name, domain_name, e))
                        configure_result[domain_name]['param_result'][param_name] = {"suc": False, "value": "", "msg": "{}".format(e)}
                
                except Exception as e:
                    continue
                
            # Remove handled feature in 'param_list'
            for f in handled_feature:
                param_list.pop(f)            

            # All param handled in feature-level handler
            if param_list.__len__() == 0:
                continue
            
            try:
                domain_handler = get_domain_handler(domain_name)
                try:
                    if request_data["readonly"]:
                        for param_name, res in domain_handler.get_values(param_list).items():
                            configure_result[domain_name]['param_result'][param_name] = res
                        
                    else:
                        for param_name, res in domain_handler.set_values(param_list).items():
                            configure_result[domain_name]['param_result'][param_name] = res
                        
                    configure_result[domain_name]['suc'] = True
                    configure_result[domain_name]['msg'] = ""
                    
                except Exception as e:
                    logger.error("configure '{}' failed: {}".format(domain_name, e))
                    configure_result[domain_name]['suc'] = False
                    configure_result[domain_name]['msg'] = "{}".format(e)
            
            except Exception as e:
                configure_result[domain_name]['suc'] = False
                configure_result[domain_name]['msg'] = "no acceptable handler of '{}': {}".format(domain_name, e)
        
        logger.debug("configure response data: {}".format(configure_result))
        self.write(json.dumps(configure_result))
        self.finish()